package com.example.demo.controller;


import com.example.demo.model.*;
import com.example.demo.repository.ApplicationInformationRepository;
import com.example.demo.repository.EnterpriseInfoRepository;
import com.example.demo.util.AddressUtil;
import com.example.demo.util.AppUtil;
import com.example.demo.util.LangUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


/**
 * Created by huang on 2018/1/9.
 */
@RequestMapping("/api/v1")
@RestController
@Transactional
public class ApplicationCRUDController extends BaseController {

    @Autowired
    ApplicationInformationRepository applicationInformationRepository;
    @Autowired
    EnterpriseInfoRepository enterpriseInfoRepository;

    @GetMapping("applications")
    public ReturnDTO query(HttpServletRequest request0) {
        PageRequest request1 = this.buildPageRequest(request0);
        Page<ApplicationInformation> applicationInformationList;
        String status = request0.getParameter("status");
        String creditCode = request0.getParameter("creditCode");
        String companyName = request0.getParameter("companyName");
        String[] createTime = request0.getParameterValues("createTime");
        applicationInformationList = this.applicationInformationRepository.findAll(getWhereClause(status, creditCode, companyName, createTime), request1);
        ReturnDTO returnDTO = new ReturnDTO();
        returnDTO.setData(applicationInformationList.getContent());
        returnDTO.setTotal(applicationInformationList.getTotalElements());
        return returnDTO;

    }
    @PostMapping("applications")
    public ResponseEntity create(@RequestBody ApplicationInformation applicationInformation) {
        applicationInformation.setProvince(AddressUtil.getProvinceByFullCode(applicationInformation.getCreditCode()));
        applicationInformationRepository.save(applicationInformation);
        List<EnterpriseInfo> enterpriseInfo = enterpriseInfoRepository.findByCreditCode(applicationInformation.getCreditCode());
        EnterpriseInfo enterpriseInfo1;
        if(enterpriseInfo.size() == 0 ){
            enterpriseInfo1 = new EnterpriseInfo();
        }else{
            enterpriseInfo1 = enterpriseInfo.get(0);
        }
        BeanUtils.copyProperties(applicationInformation ,enterpriseInfo1, new String[]{"id"});
        enterpriseInfoRepository.save(enterpriseInfo1);
        return new ResponseEntity("Successfully!", HttpStatus.OK);
    }

    @GetMapping("applications/{id}")
    public ApplicationInformationDTO queryById(HttpServletRequest request0, @PathVariable int id) {
        ApplicationInformation applicationInformation = applicationInformationRepository.findById(id);
        ApplicationInformationDTO applicationInformationDTO = new ApplicationInformationDTO();
        BeanUtils.copyProperties(applicationInformation, applicationInformationDTO);
        applicationInformationDTO.setSecretCommittee(AppUtil.rowToMatrix(applicationInformation.getSecretCommittee()));
        applicationInformationDTO.setMtcsol(AppUtil.rowToMatrix(applicationInformation.getMtcsol()));
        return applicationInformationDTO;

    }

    @PutMapping("applications/{id}")
    public void update(@PathVariable int id, @RequestBody ApplicationInformationDTO applicationInformationDTO) {
        ApplicationInformation applicationInformation = applicationInformationRepository.findById(id);
        applicationInformation.getSecretCommittee().clear();
        applicationInformation.getMtcsol().clear();
        LangUtil.copyPropertiesIgnoreNull(applicationInformationDTO, applicationInformation, new String[]{"id", "mtcsol", "secretCommittee"});
        if(applicationInformation.getSource().equals("导入")){
            List list = AppUtil.matrixToRow(applicationInformationDTO.getSecretCommittee());
            applicationInformation.getSecretCommittee().addAll(list);
            applicationInformation.getMtcsol().addAll(AppUtil.matrixToRow(applicationInformationDTO.getMtcsol()));
            applicationInformation.setProvince(AddressUtil.getProvinceByFullCode(applicationInformation.getCreditCode()));
        }
        applicationInformationRepository.save(applicationInformation);
    }

    @DeleteMapping("applications/{id}")
    public void delete(@PathVariable int id) {
        applicationInformationRepository.deleteById(id);
    }

    private Specification<ApplicationInformation> getWhereClause(final String status, final String creditCode, final String companyName, final String[] createTime) {
        return new Specification<ApplicationInformation>() {
            @Override
            public Predicate toPredicate(Root<ApplicationInformation> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.conjunction();

                if (!StringUtils.isEmpty(status)) {
                    predicate.getExpressions().add(
                            criteriaBuilder.and(criteriaBuilder.or(root.<String>get("acceptResult").in(status), root.<String>get("writtenResult").in(status)))

                    );
                }
                if (!StringUtils.isEmpty(creditCode)) {
                    predicate.getExpressions().add(
                            criteriaBuilder.and(root.<String>get("creditCode").in(creditCode)));
                }
                if (!StringUtils.isEmpty(companyName)) {
                    predicate.getExpressions().add(
                            criteriaBuilder.and(root.<String>get("companyName").in(companyName)));
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                if (!StringUtils.isEmpty(createTime)) {
                    try {
                        predicate.getExpressions().add(
                                criteriaBuilder.between(root.<Date>get("createTime"), sdf.parse(createTime[0]), sdf.parse(createTime[1]))
                        );
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
                return predicate;
            }
        };
    }

    @PostMapping("applications/handleAcceptResult")
    public ResponseEntity acceptResult(@RequestBody AcceptResultDTO acceptResultDTO) throws IOException, ParseException {
        ApplicationInformation applicationInformation = applicationInformationRepository.findById(acceptResultDTO.getId());
        if(applicationInformation.getUpload() == null){
            applicationInformation.setUpload(new Upload());
        }
        BeanUtils.copyProperties(acceptResultDTO, applicationInformation);
        applicationInformation.getUpload().setSuggestionFile(acceptResultDTO.getSuggestionFile());
        applicationInformationRepository.save(applicationInformation);
        return new ResponseEntity("Successfully!", HttpStatus.OK);
    }

    @PostMapping("applications/handleWrittenResult")
    public ResponseEntity writtenResult(@RequestBody WrittenResultDTO writtenResultDTO) throws IOException, ParseException {
        ApplicationInformation applicationInformation = applicationInformationRepository.findById(writtenResultDTO.getId());
        if(applicationInformation.getUpload() == null){
            applicationInformation.setUpload(new Upload());
        }
        BeanUtils.copyProperties(writtenResultDTO, applicationInformation);
        applicationInformation.getUpload().setRecordFile(writtenResultDTO.getRecordFile());
        applicationInformationRepository.save(applicationInformation);
        return new ResponseEntity("Successfully!", HttpStatus.OK);
    }

}
